#include "gamemaster.h"
#include "card.h"
#include "hand.h"
#include "Player.h"
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <QStringList>
//#include "game.h"
#include <QtCore>
#include <QThread>
#include "NetworkPlayer.h"

//#include "AIPlayer.h"
using namespace std;
// created by NA Molapo and AB Arakkal
// edited by CP botha
GameMaster::GameMaster(Server * s)
{
    server=s;
    idShuffled = new int[52];
    initializeDeck();
    Hand h;
    gameDone = false;

    for(int i=0; i<4;i++)      //beginning of the game the score is 0
    {
        scores[i] = 0;
        TrickWins[i] = 0;
        players[i] = new NetworkPlayer(h,i,NULL,server);// create four Network players
    }

    players[0]->partner=players[2];     // set player partnets
    players[2]->partner=players[0];
    players[1]->partner=players[3];
    players[3]->partner=players[1];

    trickNumber=0;                  // initialize all game master vaiables
    dealNumber=0;
    gameNumber=0;

    overT[0] = 0;
    overT[1] = 0;

    nsWonGames = 0;
    ewWonGames = 0;

    gamesWon[0]=0;
    gamesWon[1]=0;

    redeal=false;
}
// created by NA Molapo
GameMaster::~GameMaster()
{
    delete idShuffled;
    delete [] players;
}
// created by CP Botha
void GameMaster::run()
{
    qDebug() << endl << "=========== START GAMEMASTER ============";

    qDebug() << "______________________________________________________";
    qDebug() << QString::fromStdString(players[0]->getUsername()) << "Partnered with: " << QString::fromStdString(players[2]->getUsername());
    qDebug() << QString::fromStdString(players[1]->getUsername()) << "Partnered with: " << QString::fromStdString(players[3]->getUsername());

    do
    {
        do
        {
            redeal=false;
            shuffle();      // shuffle cards
            deal();         // deal cards
            bidding();      // do bidding
        } while(redeal);

        playing();          //do playing

        if( gamesWon[0]==2 ||  gamesWon[1]==2)      // determine rubber winner
        {
            gameDone=true;
            if(gamesWon[0]==2)
                for(int i=0;i<4;i++)
                    players[i]->sendRubberWinner("north_south");
            else
                for(int i=0;i<4;i++)
                    players[i]->sendRubberWinner("east_west");
        }
    } while(!gameDone);

}
// created by NA Molapo
void GameMaster::initializeDeck() // place all cards from a standart deck in a list of cards
{
    int o= 1;   // NULL: dont assing onwner yet
    string num;
    char *s = new char[2];

    int j=0; //iterarator
    for(int i=0;i<8;i++)
    {
        itoa(i+2,s,10);
        num ="0" +string(s);
        deck.push_back(Card('S',i+1,o,num));
    }
    deck.push_back(Card('S',9,o,"10"));
    deck.push_back(Card('S',10,o,"0J"));
    deck.push_back(Card('S',11,o,"0Q"));
    deck.push_back(Card('S',12,o,"0K"));
    deck.push_back(Card('S',13,o,"0A"));

    for(int i=13;i<21;i++)
    {
        itoa(j+2,s,10);
        num ="0" +string(s);
        deck.push_back(Card('H',i+1,o,num));
        j++;
    }
    deck.push_back(Card('H',22,o,"10"));
    deck.push_back(Card('H',23,o,"0J"));
    deck.push_back(Card('H',24,o,"0Q"));
    deck.push_back(Card('H',25,o,"0K"));
    deck.push_back(Card('H',26,o,"0A"));

    j=0;
    for(int i=26;i<34;i++)
    {
        itoa(j+2,s,10);
        num ="0" +string(s);
        deck.push_back(Card('D',i+1,o,num));
        j++;
    }
    deck.push_back(Card('D',35,o,"10"));
    deck.push_back(Card('D',36,o,"0J"));
    deck.push_back(Card('D',37,o,"0Q"));
    deck.push_back(Card('D',38,o,"0K"));
    deck.push_back(Card('D',39,o,"0A"));

    j=0;
    for(int i=39;i<47;i++)
    {
        itoa(j+2,s,10);
        num ="0" +string(s);
        deck.push_back(Card('C',i+1,o,num));
        j++;
    }
    deck.push_back(Card('C',48,o,"10"));
    deck.push_back(Card('C',49,o,"0J"));
    deck.push_back(Card('C',50,o,"0Q"));
    deck.push_back(Card('C',51,o,"0K"));
    deck.push_back(Card('C',52,o,"0A"));

    delete s;
}
// created by NA Molapo
void GameMaster::shuffle() //shuffles the IDs
{
    int ids[52];        // to store card IDs
    int random;
    unsigned int seed = time(0);
    srand(seed);                // seed the rand num generator
    //bool status = true;
    for(int i = 0; i < 52; i++)
    {
        if(i == 0)
        {
            random = 1 + rand()% 52;
            ids[i]= random;
        }
        else
        {
            random = 1 + rand()% 52;
            while (helperShuffle(i, random,ids)== true) // do when there is a duplicate
            {
                random = 1 + rand()% 52;
                helperShuffle(i,random,ids);
            }
            ids[i]= random;
        }
    }

    for(int i=0;i<52;i++) // print out shuffle IDs
    {
        idShuffled[i]=ids[i];
    }
}
// created by NA Molapo
bool GameMaster::helperShuffle(int size,int random,int ids[])
{
    bool status = false;
    for(int j = 0; j < size; j++)
    {
       if( ids[j] == random)
           status = true;         // true => there is a duplicate
    }
    return status;
}

// created by NA Molapo and AB Arakkal

void GameMaster::deal()     // assign card to owner
{

    qDebug() << endl << "=========== START DEALING ============";
    Hand h1;
    Hand h2;
    Hand h3;        // created four hands and add the cards equally from the shuffled deck
    Hand h4;
    int i;     //position in idShuffled

    for(i=0;i<52;i++)
    {
        for(list<Card>::iterator pos = deck.begin(); pos != deck.end();pos++)
        {
            if(pos->id == idShuffled[i])
            {

               if(i == 0 || i<13)
               {
                 pos->owner=0;
                 h1.addCard(*pos);


               }
               else if(i == 13 || i<26)
               {
                    pos->owner=1;
                 h2.addCard(*pos);

               }
               else if(i == 26 || i<39)
               {
                    pos->owner=2;
                 h3.addCard(*pos);

               }
               else
               {
                    pos->owner=3;
                 h4.addCard(*pos);


               }

            }
        }
    }

    //inform Players about the beginning of dealing

    for(int i=0; i<4;i++)
     {

        players[i]->startDealing();    //inform players about dealing
     }


    qDebug() << "Finished dealing.";

    players[0]->setLocalHand(h1);
    players[1]->setLocalHand(h2);           //set each players local hand
    players[2]->setLocalHand(h3);
    players[3]->setLocalHand(h4);


    for(int i=0; i<4;i++)
     {
        players[i]->id=i;
        players[i]->sendHand();    //inform players about dealing
     }

    srand(1);
    int d = 0 + rand()% 3;
   // cout<<" player that deals "<<d<<"\n";
    players[d]->dealer = true;




    dealNumber++;  // increament number of deals


}

// created by NA Molapo,CP botha and AB Arakkal
void GameMaster::bidding()
{
    //inform Players about bidding

    qDebug() << endl << "=========== START BIDDING ============";

    for(int i=0; i<4;i++)
     {

        players[i]->startBidding();    //inform players about bidding
     }

    int passCount=0;
    currPlayer=0;
    QStringList currBid;

    while(passCount<3 || highestBid.isEmpty())
    {
        currBid=players[currPlayer]->getBid();          // ask player for a bid
        currBid.append(QString::fromStdString(players[currPlayer]->getUsername())); // add player username to bid
        qDebug()<<currBid;
        qDebug()<<currBid.at(0);

        if(currBid.at(0).compare("P")==0) // check if player passed
        {
            passCount++;

           // qDebug()<<"PassCount"<<passCount;
            if(passCount>=4)            // if four passes in a row start redealing phase
            {
                for(int i=0; i<4;i++)
                    players[i]->startRedealing();    //inform players about dealing

                // qDebug()<<"Redeal";
                redeal=true;
                return;
            }
        }
        else
        {

            while(!validateBid(currBid))        // if bid is invalid keep asking player for a bid until a valid bid is returnerd
            {
                players[currPlayer]->bidInvalid();
                currBid=players[currPlayer]->getBid();
                currBid.append(QString::fromStdString(players[currPlayer]->getUsername()));
            }


        }
        if(currBid.at(0).compare("P")!=0) // if player did not pass reset the pass counter
        {
             passCount=0;
        }
        for(int i=0; i<4;i++)
            players[i]->sendBid( currBid,i); //send valid bid out to all players

        currPlayer++;                   // change current player
        currPlayer=currPlayer%4;
    }
        for (int j= 0; j<4 ; j++) // once bidding has ended send contract out to all players
       {
           players[j]->sendContract(highestBid);
           //if(highestBid.at(2).compare("NT")!=0)
               trumpSuit=highestBid.at(2).at(0);
            players[j]->updateTrump(trumpSuit);     // update all trump suits
             players[j]->print();

       }

       // determine declarer

        if(players[highestBidPlayer]->partner->highestBid.isEmpty())   // determin who is the dummy and who is the declarer
        {
            players[highestBidPlayer]->partner->dummyFlag=true;
           players[highestBidPlayer]->declarer=true;
            dummy = players[highestBidPlayer]->partner;
            firstPlayer=highestBidPlayer;
        }
        else
            if(players[highestBidPlayer]->highestBid.at(2).compare(players[highestBidPlayer]->partner->highestBid.at(2))==0)
            {
                players[highestBidPlayer]->dummyFlag=true;
                players[highestBidPlayer]->partner->declarer=true;
                 dummy= players[highestBidPlayer];
                highestBidPlayer=highestBidPlayer+1;
                highestBidPlayer=highestBidPlayer%4;
                firstPlayer=highestBidPlayer;
            }
        else
            {
                players[highestBidPlayer]->partner->dummyFlag=true;
                players[highestBidPlayer]->declarer=true;
                 dummy= players[highestBidPlayer]->partner;
                firstPlayer=highestBidPlayer;
            }

        for(int i=0; i<4;i++)               // send dummy id to all players
            players[i]->sendDummyId(dummy->getUsername());

        firstPlayer++;
        firstPlayer=firstPlayer%4;
}
// created by NA Molapo and AB Arakkal
bool GameMaster::validateBid(QStringList bid)
{
    QStringList suits;
    suits.append("H");
    suits.append("S");
    suits.append("D");
    suits.append("C");
    suits.append("NT");

    bool validSuit=false;

    if(bid.at(0)=="P")
        return true;

    for(int i=0;i<bid.length();i++)
        if(bid.at(i)=="" || bid.at(i)=="0") // invalid bid information
            return false;

    for(int i=0;i<suits.length();i++)
    {
        if(bid.at(2).compare(suits.at(i))==0)
        {
            validSuit=true;
            break;
        }
    }

    if(!validSuit)          // invalid bid suit
        return false;

    if(highestBid.isEmpty())            // if player is first to bid bid is always valid
    {
        highestBid=bid;
        highestBidPlayer=currPlayer;
        players[currPlayer]->highestBid=bid;
        return true;
    }

    QString bidString="";
    QString HighString="";

    bidString.append(bid.at(2));
    bidString.append(bid.at(1));
    HighString.append(highestBid.at(2));
    HighString.append(highestBid.at(1));

    if(validateHelper(bidString)<=validateHelper(HighString)) // test if bif is higher that last bid
        return false;

    highestBid=bid;
    highestBidPlayer=currPlayer;                // set new highest bid
    players[currPlayer]->highestBid=bid;

    return true;

}
// created by NA Molapo and AB Arakkal
int GameMaster::validateHelper(QString b) // returns int value of bid
{
    int val;
        qDebug()<<"helper";

        if(b.compare("C1")==0){val = 1;}
        else if(b.compare("D1")==0){val = 2;}
        else if(b.compare("H1")==0){val = 3;}
        else if(b.compare("S1")==0){val = 4;}
        else if(b.compare("NT1")==0){val = 5;}
        else if(b.compare("C2")==0){val = 6;}
        else if(b.compare("D2")==0){val = 7;}
        else if(b.compare("H2")==0){val = 8;}
        else if(b.compare("S2")==0){val = 9;}
        else if(b.compare("NT2")==0){val = 10;}
        else if(b.compare("C3")==0){val = 11; }
        else if(b.compare("D3")==0){val = 12; }
        else if(b.compare("H3")==0){val = 13; }
        else if(b.compare("S3")==0){val = 14; }
        else if(b.compare("NT3")==0){val = 15; }
        else if(b.compare("C4")==0){val = 16; }
        else if(b.compare("D4")==0){val = 17; }
        else if(b.compare("H4")==0){val = 18; }
        else if(b.compare("S4")==0){val = 19; }
        else if(b.compare("NT4")==0){val = 20; }
        else if(b.compare("C5")==0){val = 21; }
        else if(b.compare("D5")==0){val = 22; }
        else if(b.compare("H5")==0){val = 23; }
        else if(b.compare("S5")==0){val = 24; }
        else if(b.compare("NT5")==0){val = 25; }
        else if(b.compare("C6")==0){val = 26; }
        else if(b.compare("D6")==0){val = 27; }
        else if(b.compare("H6")==0){val = 28; }
        else if(b.compare("S6")==0){val = 29; }
        else if(b.compare("NT6")==0){val = 30; }
        else if(b.compare("C7")==0){val = 31; }
        else if(b.compare("D7")==0){val = 32; }
        else if(b.compare("H7")==0){val = 33; }
        else if(b.compare("S7")==0){val = 34; }
        else if(b.compare("NT7")==0){val = 35; }
        else{ ;}

        return val;
}
// created by NA Molapo and AB Arakkal
int GameMaster::validateHelper2(QString b) // returns int value of bid
{
    int val;

        if(b.compare("C1")==0){val = 1;}
        else if(b.compare("D1")==0){val = 2;}
        else if(b.compare("H1")==0){val = 3;}
        else if(b.compare("S1")==0){val = 4;}
        else if(b.compare("NT1")==0){val = 5;}
        else if(b.compare("C2")==0){val = 6;}
        else if(b.compare("D2")==0){val = 7;}
        else if(b.compare("H2")==0){val = 8;}
        else if(b.compare("S2")==0){val = 9;}
        else if(b.compare("NT2")==0){val = 10;}
        else if(b.compare("C3")==0){val = 11; }
        else if(b.compare("D3")==0){val = 12; }
        else if(b.compare("H3")==0){val = 13; }
        else if(b.compare("S3")==0){val = 14; }
        else if(b.compare("NT3")==0){val = 15; }
        else if(b.compare("C4")==0){val = 16; }
        else if(b.compare("D4")==0){val = 17; }
        else if(b.compare("H4")==0){val = 18; }
        else if(b.compare("S4")==0){val = 19; }
        else if(b.compare("NT4")==0){val = 20; }
        else if(b.compare("C5")==0){val = 21; }
        else if(b.compare("D5")==0){val = 22; }
        else if(b.compare("H5")==0){val = 23; }
        else if(b.compare("S5")==0){val = 24; }
        else if(b.compare("NT5")==0){val = 25; }
        else if(b.compare("C6")==0){val = 26; }
        else if(b.compare("D6")==0){val = 27; }
        else if(b.compare("H6")==0){val = 28; }
        else if(b.compare("S6")==0){val = 29; }
        else if(b.compare("NT6")==0){val = 30; }
        else if(b.compare("C7")==0){val = 31; }
        else if(b.compare("D7")==0){val = 32; }
        else if(b.compare("H7")==0){val = 33; }
        else if(b.compare("S7")==0){val = 34; }
        else if(b.compare("NT7")==0){val = 35; }
        else{ val = -1;}

        return val;
}
// created by NA Molapo,CP botha and AB Arakkal
void GameMaster::playing()
{
    qDebug() << "=========== START PLAYING ============";

    //inform Players about start of game play
      Card currPlay (' ',0 ,0,"");

    for(int i=0; i<4;i++)
    {
        players[i]->startPlay(); // alert players that bidding has started
    }

    currPlayer=firstPlayer;
    openingLead=true;
    for(int tricks=0;tricks<13;tricks++) // player 13 tricks
    {
        trickNumber++;
        qDebug()<<"GM sending game Status";

        QStringList status;
        status.append(QString::number(trickNumber));
        status.append(QString::number(dealNumber));
        status.append(QString::number(gameNumber));

        for(int i=0;i<4;i++)
            players[i]->sendGameStatus(status);  //send out game startus
        qDebug()<<"===========New trick============"<<trickNumber;
        trick=new Hand();
        for(int plays=0;plays<4;plays++) // allow each player to play once in the current trick
        {

           // for(int i=0;i<4;i++)

            if(players[currPlayer]->dummyFlag)
               currPlay=players[currPlayer]->partner->getMove(true); // if player is dummy ask his partner to play for him
            else
                currPlay=players[currPlayer]->getMove(false);           // ask player to play
            qDebug()<<"["<<currPlayer<<"]"<<currPlay.suit<<" - "<<QString::fromStdString(currPlay.num);

            while(!validateMove(currPlay))      // validate move and keep asking player until a valid move is returned
            {
                qDebug()<<"Invalid move";
               //  players[currPlayer]->print();
                if(players[currPlayer]->dummyFlag)
                   currPlay=players[currPlayer]->partner->getMove(true);
                else
                    currPlay=players[currPlayer]->getMove(false);
                    qDebug()<<currPlay.suit<<" - "<<QString::fromStdString(currPlay.num);
            }

            for(int i=0;i<4;i++)
            {
                //qDebug()<<"Gm sends moves";
                players[i]->sendMove(currPlay,QString::fromStdString(players[currPlayer]->getUsername())); // send valid move out to all players
            }

            trick->addCard(currPlay);                   // add valid move to current trick
            players[currPlayer]->localHand.removeCard(currPlay);

            if(openingLead)         // test if the game is opening
            {
                openingLead=false;
                for(int k=0;k<4;k++)
                    if(players[k]->dummyFlag)
                    {
                        for(int i=0;i<4;i++)
                            players[i]->sendDummyCards(dummy->localHand);   // send out dummy cards after first play
                        break;
                    }
            }


            currPlayer++;
            currPlayer=currPlayer%4;
        }
        // determine trick winner;

         QString winner=determineTrickWinner();     // determine trick winner

         for( int i=0; i<4; i++)
             players[i]->sendTrickWinner( winningTeam, winner);  //send trick winner out to all players

         currPlayer = trickWinner;                // next player is player that won the previous trick



         // calculate score


                        int points = 0;

                        if(trickMax->trump == 0)  //Non trump
                        {

                            if(trickNumber == 1) { //first trick
                                points = 40;

                            }
                            else                // other tricks
                            {
                                points = 30;

                            }
                        }
                        else                // trump card won
                        {
                            if(trickMax->suit == 'S' || trickMax->suit == 'H') // trump is major suit
                            {
                                points = 30;

                            }
                            else                    // trump is minor suit
                                points = 20;
                        }

                        if(players[trickWinner]->partner->dummyFlag )    // player that won trick is declearer
                        {
                            if(players[trickWinner]->specials == "D")
                                 points = points * 2;
                            else if(players[trickWinner]->specials == "RD")
                                points = (points *2)*2;
                            else
                                ;


                        }


                        //qDebug()<<"overT: "<<overT[0];
                        if(!over)
                        {
                            scores[trickWinner] = scores[trickWinner] + points ;
                        }
                        else
                        {
                            ;
                        }



                delete trick;
            }

            qDebug()<<highestBid;
            qDebug()<<highestBidPlayer;
            qDebug()<<"Trick wins";
                 for(int i=0;i<4;i++)
                     qDebug()<<i<<" won "<<TrickWins[i]<<" tricks";

                 determineScore();
                 qDebug()<<nsAbove;
                 qDebug()<<nsBelow;
                 qDebug()<<ewAbove;
                 qDebug()<<ewBelow;

                 QString wa = nsAbove.join(",");
                 QString wb = nsBelow.join(",");
                 QString ta = ewAbove.join(",");
                 QString tb = ewBelow.join(",");


                 for( int i=0; i<4; i++)
                 {
                     players[i]->updateScore(wa,wb,ta,tb);// send score update to all players
                 }

                 TrickWins[0] = 0;
                 TrickWins[1] = 0;
                 TrickWins[2] = 0;
                 TrickWins[3] = 0;

                 if(TrickWins[0]+TrickWins[2]>TrickWins[1]+TrickWins[3])  // determine game winner(team) and send it out to all players
                 {
                     gamesWon[0]++;
                     for(int i=0;i<4;i++)
                         players[i]->sendGameWinner("north_south");
                 }
                 else
                 {
                      gamesWon[1]++;
                      for(int i=0;i<4;i++)
                          players[i]->sendGameWinner("east_west");
                 }


                 highestBid.clear();
                 highestBidPlayer = NULL;
                 trickNumber = 0;




}
// created by CP botha
bool GameMaster::validateMove(Card c)
{

    char trickSuit=trick->getCard(0)->suit;

    qDebug()<<"trick suit = "<<trickSuit<<" trump suit "<<trumpSuit;
    if(trick->getHandSize()==0)             //if trick is empty player can play any card
        return true;
     qDebug()<<"trick not empty";


    if(!players[currPlayer]->hasCardsInSuit(trickSuit)) // if player has no cards in trick suit he can play any card
        return true;
     qDebug()<<"has cards in trick suit";
    if(c.suit==trickSuit)                               // if player card is in trick suit it is valid
        return true;
     qDebug()<<"card not in same suit as trick";
    players[currPlayer]->localHand.print();
    return false;                                       // card if invalid at this point
}
// created by NA Molapo and AB Arakkal
bool GameMaster::validateMove(char leadSuit,Card h, int pos)  //returns true:1 if move is valid
{
    if (leadSuit==h.suit||h.trump==1)
        return true;
    if(!players[pos]->hasCardsInSuit(leadSuit))
        return true;
    else
        return false;
}
// created by NA Molapo and AB Arakkal
void GameMaster::determineScore()
{
        dealNumber++;
        int ns = 0;   // to store the total score of the team NS
        int ew = 0;   // to store the total score of the team EW
        int made = 0, tomake = 0;;
        int penalty = 0;
        int doubleBonus = 0;
        int slamBonus = 0;
        int nsTotal = 0;
        int ewTotal = 0;
        int penaltyAwarded = 0;           //penalty points awarded to NS:0|EW:1


        ns = scores[0]+ scores[2];
        ew = scores[1]+ scores[3];

        //update scores[]
        //scores [0] = ns;
       // scores [2] = ew;
       // scores [1] = ns;
        //scores [3] = ew;

        QString tmp ;
        int contractOwner=highestBidPlayer;



qDebug()<<"Here ==================="<<contractOwner;
        if(contractOwner == 0 || contractOwner == 2)  //contract belongs to NS
       {
           made = TrickWins[0] + TrickWins[2];
           tomake = 6 + highestBid.at(1).toInt();
           penaltyAwarded = 1;       //awarded to EW
           if(made == 12)
           {
               if(players[contractOwner]->vulnerable == 1)         //player is vulnerable
               {
                   slamBonus = 750;
               }
               else
                   slamBonus = 500;
           }
           if(made == 13)
           {
               if(players[contractOwner]->vulnerable == 1)         //player is vulnerable
               {
                   slamBonus = 1500;
               }
               else
                   slamBonus = 1000;
           }

        }
        else                //contract belongs to EW
        {
            made = TrickWins[1] + TrickWins[3];
            tomake = 6 + highestBid.at(1).toInt();
            penaltyAwarded = 0;        //awarded to NS

            if(made == 12)
            {
                if(players[contractOwner]->vulnerable == 1)         //player is vulnerable
                {
                    slamBonus = 750;
                }
                else
                    slamBonus = 500;
            }
            if(made == 13)
            {
                if(players[contractOwner]->vulnerable == 1)         //player is vulnerable
                {
                    slamBonus = 1500;
                }
                else
                    slamBonus = 1000;
            }
        }

        if(made < tomake)          //assign undertrick points to opposing team
        {
           numUnder = tomake - made;   //number of ander tricks

           int winner =( contractOwner +1)%4;  // the other team wins
           players[trickWinner]->winner = true;
           if(winner == 0 || winner == 2)
               nsWonGames++;
           else
               ewWonGames++;

        }
        else
        {
           numUnder = 0;
           players[contractOwner]->winner = true;

           if(contractOwner == 0 || contractOwner == 2)
           {

               nsWonGames++;
               tmp = QString::number(ns);
               nsBelow.append(tmp);
           }
           else
           {
               ewWonGames++;
               tmp = QString::number(ew);
               ewBelow.append(tmp);
           }


        }

        if(players[contractOwner]->vulnerable == 1)         //player is vulnerable
        {
            if(numUnder > 0)  // contract not made
            {
                if(highestBid.at(0) == "B")
                {
                    penalty = numUnder * 100;
                }
                else
                {
                    if(numUnder == 1)
                    {
                        if(highestBid.at(0) == "D")
                        {
                            penalty = numUnder * 200;

                        }
                        else
                        {
                            penalty = numUnder * 400;

                        }
                    }
                    else
                    {
                        if(highestBid.at(0) == "D")
                        {
                            penalty = numUnder * 300;

                        }
                        else
                          {
                            penalty = numUnder * 600;

                        }
                    }

                }
            }
            else       //cotract made
            {
                if(highestBid.at(0) == "D")
                {
                    doubleBonus = 50;
                }
                else
                    if(highestBid.at(0) == "RD")
                {
                    doubleBonus = 100;
                    qDebug()<<"why r u here?";
                }
                else
                        doubleBonus=0;

            }

        }

        else           //player not vulnerable
        {
           // qDebug()<<highestBid.at(0);
            if(numUnder > 0)  // contract not made
            {
                if(highestBid.at(0) == "B")
                {
                    penalty = numUnder * 50;
                    qDebug()<<"penalty:"<<penalty;
                }
                else
                {
                    if(numUnder == 1)
                    {
                        if(highestBid.at(0) == "D")
                        {
                            penalty = numUnder * 100;

                        }
                        else
                        {
                            penalty = numUnder * 200;

                        }
                    }
                    else if(numUnder == 2 || numUnder == 3)
                    {
                        if(highestBid.at(0) == "D")
                        {
                            penalty = numUnder * 200;

                        }
                        else
                        {
                            penalty = numUnder * 400;

                        }

                    }
                    else
                    {
                        if(highestBid.at(0) == "D")
                        {
                            penalty = numUnder * 300;

                        }
                        else
                        {
                            penalty = numUnder * 600;

                        }
                    }
                }
            }
            else       //cotract made
            {
                if(highestBid.at(0) == "D")
                {
                    doubleBonus = 50;
                }
                else
                    if(highestBid.at(0) == "RD")
                {
                    doubleBonus = 100;
                    qDebug()<<"why r u here?";
                }
                else
                        doubleBonus=0;


            }

        }

       //-------------------- Award points ----------------------

        if(contractOwner == 0 || contractOwner == 2)  //contract belongs to NS
        {
            if(numUnder > 0)  // contract not made
            {
                tmp = QString::number(penalty);
                ewAbove.append(tmp);
            }
            else
            {
                tmp = QString::number(overT[0]);
                nsAbove.append(tmp);
                tmp = QString::number(slamBonus);
                nsAbove.append(tmp);
                tmp = QString::number(doubleBonus);
                nsAbove.append(tmp);
                tmp = QString::number(players[0]->honourPoints + players[2]->honourPoints );
                nsAbove.append(tmp);
            }
        }
        else           //contract belongs to EW
        {
            if(numUnder > 0)  // contract not made
            {
                tmp = QString::number(penalty);
                nsAbove.append(tmp);
            }
            else
            {
                tmp = QString::number(overT[1]);
                ewAbove.append(tmp);
                tmp = QString::number(slamBonus);
                ewAbove.append(tmp);
                tmp = QString::number(doubleBonus);
                ewAbove.append(tmp);
                tmp = QString::number(players[1]->honourPoints + players[3]->honourPoints );
                ewAbove.append(tmp);

            }
        }


        //inform Players about scores
}
// created by NA Molapo and AB Arakkal
string GameMaster::determineWinner()
{
    if(nsWonGames == 1)  //player is vulnerable if they have won 1 game
        {
            players[0]->vulnerable = true;
            players[2]->vulnerable = true;
        }
        else if(ewWonGames == 1)
        {
            players[1]->vulnerable = true;
            players[3]->vulnerable = true;
        }
        else
        {
            for(int j = 0; j< 4 ; j++)
                players[j]->vulnerable = false;
        }

        for(int i = 0; i< 4 ; i++)
        {
            if(players[i]->winner == 1)
            {
                if(i== 0 || i == 2)
                    return "NS";
                else
                    return "EW";
            }
        }
}
// created by CP botha
void GameMaster:: print()
{
    for(list<Card>::iterator pos = deck.begin(); pos != deck.end();pos++)
    {
          pos->print();
          cout<<",";

    }


   // cout<<"\n";
}
// created by NA Molapo,CP botha and AB Arakkal
void GameMaster::ack()
{
    ackCount++;
}
// created by NA Molapo and AB Arakkal
void GameMaster::setPlayerName(int i,string name)
{
    players[i]->setUsername(name);
}
// created by NA Molapo and AB Arakkal
QString GameMaster::determineTrickWinner()
{

    qDebug()<<"Start determine winner";
   char tricSuit=trick->getCard(0)->suit;
   for(int i=0;i<trick->getHandSize();i++)
   {
       if(trick->getCard(i)->suit==trumpSuit)
           trick->getCard(i)->trump=true;

       if(trick->getCard(i)->suit!=tricSuit && trick->getCard(i)->trump!=true)
           trick->removeCard(*trick->getCard(i));
   }

       trickMax=trick->getMaxCard();
       trickWinner =trick->determineWinner();


       if( trickWinner == 0 || trickWinner == 2)
           winningTeam = "north_south";
       else
           winningTeam = "east_west";

       qDebug()<<"winner "<<trickWinner;
       TrickWins[trickWinner]++;


       int made = 0, tomake = 0;
       int overtrick = 0;
       int contractOwner=highestBidPlayer;

       for(int i = 0; i<4 ; i++)
       {
         if(players[i]->declarer == 1)
             contractOwner =i;
       }

       if(contractOwner == 0 || contractOwner == 2)  //contract belongs to NS
       {
          made = TrickWins[0] + TrickWins[2];
          tomake = 6 + highestBid.at(1).toInt();

          if(made > tomake)   // assign overtrick points
          {
              over = true;
              overtrick = (made-tomake);
              if(highestBid.at(0) == "D")
              {
                  if(players[contractOwner]->vulnerable == 1)  // player is vulnerable
                     overtrick  = overtrick * 200;
                  else
                      overtrick = overtrick * 100;
              }
              else if(highestBid.at(0) == "RD")
              {
                  if(players[contractOwner]->vulnerable == 1)  // player is vulnerable
                      overtrick = overtrick * 400;
                  else
                      overtrick = overtrick * 200;
              }
              else                // undoubled
              {
                  if(trickMax->suit == 'H' || trickMax->suit == 'S' || highestBid.at(0) == "B")
                  {
                      overtrick = overtrick * 30 ;

                  }
                  else                //minor suit
                  {
                       overtrick =overtrick * 20 ;
                  }
              }
              overT[0] = overtrick;        //update overT[]
          }


       }
       else               //contract belongs to EW
       {
           made = TrickWins[1] + TrickWins[3];
           tomake =  6 + highestBid.at(1).toInt();

           if(made > tomake)   // assign overtrick points
           {
               over = true;
               overtrick = (made-tomake);
               if(highestBid.at(0) == "D")
               {
                   if(players[contractOwner]->vulnerable == 1)  // player is vulnerable
                       overtrick = overtrick * 200;
                   else
                       overtrick = overtrick * 100;
               }
               else if(highestBid.at(0) == "RD")
               {
                   if(players[contractOwner]->vulnerable == 1)  // player is vulnerable
                       overtrick = overtrick * 400;
                   else
                       overtrick = overtrick * 200;
               }
               else                // undoubled
               {
                   if(trickMax->suit == 'H' || trickMax->suit == 'S' || highestBid.at(0) == "B")
                   {
                       overtrick = overtrick * 30 ;

                   }
                   else                //minor suit
                   {
                           overtrick = overtrick * 20 ;
                   }
               }

               overT[1] = overtrick;        //update overT[]
           }


       }
       qDebug()<<"end determine winner";
       return QString::fromStdString(players[trickWinner]->getUsername());
}
// created by CP botha
void GameMaster::playerQuit(QString name) // show name of player who quit
{
    qDebug() << "||||||||||||||||||||||||||||||||||||||||||||||";
    qDebug() << name;
    qDebug() << "||||||||||||||||||||||||||||||||||||||||||||||";
}
